//////////////////////////////////////////////////////////////////////////
/// Copyright (c) 2011, Sidorenko 'PC' Alexander                       ///
/// mailto: sidorenko /*dot*/ alexander (at) gmail [dot] com           ///
/// This file is a part of the Radiating Gas Dynamics project          ///
//////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "RGD.h"
#include "RGDDlg.h"

#include "MemDC.h"

#include "Problem/SodProblem.h"
#include "Problem/SodProblem2D.h"
#include "Problem/BrickProblem.h"

#include "AviMemDC.h"

#include "AviDlg.h"

#include "ShockDlg.h"
#include "BrickDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#include "ProgressDlg.h"

// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CRGDDlg dialog




CRGDDlg::CRGDDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CRGDDlg::IDD, pParent)
	, m_problem(NULL)
	, m_timelineHeight(0)
	, m_timeFactor(0)
{
	m_drawRect = CRect(0, 0, 0, 0);
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CRGDDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CRGDDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_COMMAND(ID_HELP_ABOUT, &CRGDDlg::OnHelpAbout)
	ON_COMMAND(ID_SIMULATION_DISCARDSOLUTION, &CRGDDlg::OnSimulationDiscardsolution)
	ON_UPDATE_COMMAND_UI(ID_SIMULATION_DISCARDSOLUTION, &CRGDDlg::OnUpdateSimulationDiscardsolution)
	ON_COMMAND(ID_SIMULATION_EXIT, &CRGDDlg::OnSimulationExit)
	ON_COMMAND(ID_SIMULATION_OPENFILE, &CRGDDlg::OnSimulationOpenFile)
	ON_COMMAND(ID_STARTNEW_SPHERE, &CRGDDlg::OnSimulationStartnewSphere)
	ON_COMMAND(ID_STARTNEW_CYLINDER, &CRGDDlg::OnSimulationStartnewCylinder)
	ON_COMMAND(ID_STARTNEW_SOD, &CRGDDlg::OnSimulationStartnewSod)
	ON_COMMAND(ID_STARTNEW_SOD32782, &CRGDDlg::OnSimulationStartnewSod2d)
	ON_COMMAND(ID_STARTNEW_BRICKFLOW, &CRGDDlg::OnSimulationStartnewBrick)
	ON_WM_CLOSE()
	ON_WM_DESTROY()
	ON_WM_SIZE()
	ON_WM_ERASEBKGND()
	ON_COMMAND(ID_STARTNEW_BUNCHOFTESTS, &CRGDDlg::OnStartnewBunchoftests)
	ON_COMMAND(ID_SIMULATION_SAVEAVI, &CRGDDlg::OnSimulationSaveavi)
END_MESSAGE_MAP()


// CRGDDlg message handlers

#include "Timer.h"

BOOL CRGDDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	// Create jet colorizer
	m_jetColor.InsertKey(SColorKey(RGB(0, 0, 143), 0.0f));
	m_jetColor.InsertKey(SColorKey(RGB(0, 0, 255), 0.125f));
	m_jetColor.InsertKey(SColorKey(RGB(0, 255, 255), 0.375f));
	m_jetColor.InsertKey(SColorKey(RGB(255, 255, 0), 0.625f));
	m_jetColor.InsertKey(SColorKey(RGB(255, 0, 0), 0.875f));
	m_jetColor.InsertKey(SColorKey(RGB(128, 0, 0), 1.0f));
	m_jetColor.SortKeys();

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	m_timeline.Create(CTimeline::IDD, this);
	m_timeline.setLisneter(this);

	m_timeline.setProblem(NULL);

	CRect timelineRect;
	m_timeline.GetWindowRect(timelineRect);
	m_timelineHeight = timelineRect.Height();
	ResizeTimeline();

	DrawCurrentSolution();

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CRGDDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CRGDDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();

		DrawCurrentSolution();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CRGDDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CRGDDlg::OnHelpAbout()
{
	CAboutDlg dlgAbout;
	dlgAbout.DoModal();
}

void CRGDDlg::OnSimulationDiscardsolution()
{
	if (m_problem != NULL)
	{
		delete m_problem;
		m_problem = NULL;
		m_timeline.setProblem(NULL);
	}
	DrawCurrentSolution();
}

void CRGDDlg::OnUpdateSimulationDiscardsolution(CCmdUI *pCmdUI)
{
	pCmdUI->Enable(m_problem != NULL);
}

void CRGDDlg::OnSimulationExit()
{
	CDialog::OnOK();
}

void CRGDDlg::OnSimulationOpenFile()
{
	CFileDialog fileDlg(TRUE, _T(".gdp"), NULL, 0, _T("Gas Dynamics Problem (*.gdp)|*.gdp||"));
	if (fileDlg.DoModal() == IDOK)
	{
		if (m_problem != NULL)
		{
			delete m_problem;
			m_problem = NULL;
			m_timeline.setProblem(NULL);
		}
		Problem *pr = Problem::readProblem(fileDlg.GetPathName().GetBuffer(0));
		if (NULL == pr)
			MessageBox("Can't open file!", "Error", MB_OK | MB_ICONERROR);
		m_timeline.setProblem(pr);
		m_problem = pr;
		DrawCurrentSolution();
	}
}

void CRGDDlg::OnSimulationStartnewSphere()
{
	//CParamsDlg pdlg;
	//CFileDialog fileDlg(FALSE, _T(".gdp"), NULL, 0, _T("Gas Dynamics Problem (*.gdp)|*.gdp||"));
	//if (pdlg.DoModal() == IDOK &&
	//	fileDlg.DoModal() == IDOK)
	//{
	//	if (m_problem != NULL)
	//	{
	//		delete m_problem;
	//		m_problem = NULL;
	//		m_timeline.setProblem(NULL);
	//	}
	//	SphereProblem *sp = new SphereProblem(gdScalar(1.4), gdScalar(0.5), fileDlg.GetPathName().GetBuffer(0));
	//	sp->initGrid(gdScalar(pdlg.m_gridSize) * pdlg.m_cellSize, pdlg.m_gridSize, pdlg.m_precision, 10);
	//	CProgressDlg dlg(sp, true);
	//	// TODO: Pass frequency information into Problem here
	//	dlg.solve(pdlg.m_experimentTime);
	//	m_timeline.setProblem(sp);
	//	m_problem = sp;
	//	DrawCurrentSolution();
	//}
}

void CRGDDlg::OnSimulationStartnewCylinder()
{
	if (m_problem != NULL)
	{
		delete m_problem;
		m_problem = NULL;
		m_timeline.setProblem(NULL);
	}
	// TODO:
}

void CRGDDlg::OnSimulationStartnewBrick()
{
	CBrickDlg pdlg;
	CFileDialog fileDlg(FALSE, _T(".gdp"), NULL, 0, _T("Gas Dynamics Problem (*.gdp)|*.gdp||"));
	if (pdlg.DoModal() == IDOK &&
		fileDlg.DoModal() == IDOK)
	{
		if (m_problem != NULL)
		{
			delete m_problem;
			m_problem = NULL;
			m_timeline.setProblem(NULL);
		}
		BrickProblem *sp = new BrickProblem(pdlg.m_gamma, pdlg.m_clf, 
											pdlg.m_threads, pdlg.m_timesteps, 
											pdlg.m_saveFull, pdlg.m_sphere, 
											pdlg.m_divider, pdlg.m_speed);
		sp->initGrid(pdlg.m_xSize, pdlg.m_gridSize, pdlg.m_precision, 10);
		CProgressDlg dlg(sp, true);
		// TODO: Pass frequency information into Problem here
		dlg.solve(pdlg.m_experimentTime, fileDlg.GetPathName().GetBuffer(0));
		delete sp;
		m_problem = Problem::readProblem(fileDlg.GetPathName().GetBuffer(0));
		m_timeline.setProblem(m_problem);
		DrawCurrentSolution();
	}
}

void CRGDDlg::OnSimulationStartnewSod2d()
{
	CShockDlg pdlg;
	CFileDialog fileDlg(FALSE, _T(".gdp"), NULL, 0, _T("Gas Dynamics Problem (*.gdp)|*.gdp||"));
	if (pdlg.DoModal() == IDOK &&
		fileDlg.DoModal() == IDOK)
	{
		if (m_problem != NULL)
		{
			delete m_problem;
			m_problem = NULL;
			m_timeline.setProblem(NULL);
		}
		SodProblem2d *sp = new SodProblem2d(pdlg.m_gamma, pdlg.m_clf, pdlg.m_threads, pdlg.m_timesteps, pdlg.m_saveFull);
		sp->initGrid(pdlg.m_xSize, pdlg.m_gridSize, pdlg.m_precision, 10);
		CProgressDlg dlg(sp, true);
		// TODO: Pass frequency information into Problem here
		dlg.solve(pdlg.m_experimentTime, fileDlg.GetPathName().GetBuffer(0));
		delete sp;
		m_problem = Problem::readProblem(fileDlg.GetPathName().GetBuffer(0));
		m_timeline.setProblem(m_problem);
		DrawCurrentSolution();
	}
}

void CRGDDlg::OnSimulationStartnewSod()
{
	CShockDlg pdlg;
	CFileDialog fileDlg(FALSE, _T(".gdp"), NULL, 0, _T("Gas Dynamics Problem (*.gdp)|*.gdp||"));
	if (pdlg.DoModal() == IDOK &&
		fileDlg.DoModal() == IDOK)
	{
		if (m_problem != NULL)
		{
			delete m_problem;
			m_problem = NULL;
			m_timeline.setProblem(NULL);
		}
		SodProblem *sp = new SodProblem(pdlg.m_gamma, pdlg.m_clf, pdlg.m_threads, pdlg.m_timesteps, pdlg.m_saveFull);
		sp->initGrid(pdlg.m_xSize, pdlg.m_gridSize, pdlg.m_precision, 10);
		CProgressDlg dlg(sp, true);
		// TODO: Pass frequency information into Problem here
		dlg.solve(pdlg.m_experimentTime, fileDlg.GetPathName().GetBuffer(0));
		delete sp;
		m_problem = Problem::readProblem(fileDlg.GetPathName().GetBuffer(0));
		m_timeline.setProblem(m_problem);
		DrawCurrentSolution();
	}
}

void CRGDDlg::OnOK()
{
	// Prevent closing when Enter is pressed
//	CDialog::OnOK();
}

void CRGDDlg::OnCancel()
{
	// Prevent closing when Esc is pressed
//	CDialog::OnCancel();
}

void CRGDDlg::OnClose()
{
	CDialog::OnOK();	
//	CDialog::OnClose();
}

void CRGDDlg::OnDestroy()
{
	CDialog::OnDestroy();

	m_timeline.DestroyWindow();
}

void CRGDDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);

	if (m_timeline.GetSafeHwnd() != 0)
	{
		ResizeTimeline();
	}

	DrawCurrentSolution();
}

//////////////////////////////////////////////////////////////////////////
void CRGDDlg::ResizeTimeline()
{
	CRect cliRect;
	GetClientRect(cliRect);

	CRect timeLineRect = cliRect;
	timeLineRect.top = timeLineRect.bottom - m_timelineHeight;
	m_timeline.MoveWindow(timeLineRect, true);

	m_drawRect = cliRect;
	m_drawRect.bottom -= m_timelineHeight;
}

//////////////////////////////////////////////////////////////////////////
void CRGDDlg::DrawCurrentSolution()
{
	CClientDC dc(this);
	if (m_problem != NULL)
	{
		unsigned int numSteps = m_problem->getNumSteps();
		unsigned int step = (unsigned int)(gdScalar(numSteps - 1) * m_timeFactor);
//		m_timeline.PlotCurrentSolution(dc, m_drawRect, m_jetColor);
		CMemDC mem(&dc, &m_drawRect);
		m_timeline.PlotCurrentSolution(mem, m_drawRect, m_jetColor);
//		m_problem->plotSolution(mem, m_drawRect, m_jetColor, step, Problem::PLOT_Density);
	}
	else
	{
		dc.FillSolidRect(m_drawRect, RGB(255, 255, 255));
	}
}

void CRGDDlg::OnPlotTypeChanged()
{
	DrawCurrentSolution();
}

void CRGDDlg::OnTimeChanged(gdScalar factor)
{
	m_timeFactor = factor;
	DrawCurrentSolution();
}

//////////////////////////////////////////////////////////////////////////
BOOL CRGDDlg::OnEraseBkgnd(CDC* pDC)
{
	return FALSE;
//	return CDialog::OnEraseBkgnd(pDC);
}

void CRGDDlg::OnStartnewBunchoftests()
{
	unsigned int time = GetTickCount();

	BrickProblem *bp = NULL;

	// TIME == 0.01
	// 512 cells
	// SPHERE
	bp = new BrickProblem(1.4, 0.5, 8, 600, true, true, 25, 100.0);
	bp->initGrid(0.1, 512, 10e-5, 10);
	{
	CProgressDlg dlg(bp, false);
	dlg.solve(0.01, "C:\\Users\\Alexander\\Desktop\\results\\sphere_512_0010t_25r_100s_600ts.gdp");
	}
	delete bp;

	// TIME == 0.01
	// 512 cells
	// BRICK
	bp = new BrickProblem(1.4, 0.5, 8, 600, true, false, 32, 100.0);
	bp->initGrid(0.1, 512, 10e-5, 10);
	{
	CProgressDlg dlg(bp, false);
	dlg.solve(0.01, "C:\\Users\\Alexander\\Desktop\\results\\brick_512_0010t_32r_100s_600ts.gdp");
	}
	delete bp;

	//SodProblem2d *sp = NULL;

	//// TIME == 0.25
	//// 500 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_025t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_025t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_025t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_025t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_025t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_025t_1t.gdp");
	//}
	//delete sp;

	//// 1000 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_025t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_025t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_025t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_025t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_025t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_025t_1t.gdp");
	//}
	//delete sp;

	//// TIME == 0.5
	//// 500 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_050t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_050t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_050t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_050t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_050t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_050t_1t.gdp");
	//}
	//delete sp;

	//// 1000 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_050t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_050t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_050t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_050t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_050t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_050t_1t.gdp");
	//}
	//delete sp;

	//// TIME == 1.0
	//// 500 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_100t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_100t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_100t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_100t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_100t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 500, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_5p_100t_1t.gdp");
	//}
	//delete sp;

	//// 1000 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_100t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_100t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_100t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_100t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_100t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 1000, 10e-5, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_5p_100t_1t.gdp");
	//}
	//delete sp;



	//// TIME == 0.25
	//// 500 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_025t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_025t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_025t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_025t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_025t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_025t_1t.gdp");
	//}
	//delete sp;

	//// 1000 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_025t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_025t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_025t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_025t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_025t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.25, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_025t_1t.gdp");
	//}
	//delete sp;

	//// TIME == 0.5
	//// 500 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_050t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_050t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_050t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_050t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_050t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_050t_1t.gdp");
	//}
	//delete sp;

	//// 1000 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_050t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_050t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_050t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_050t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_050t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(0.5, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_050t_1t.gdp");
	//}
	//delete sp;

	//// TIME == 1.0
	//// 500 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_100t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_100t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_100t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_100t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_100t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 500, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_500_10p_100t_1t.gdp");
	//}
	//delete sp;

	//// 1000 cells
	//sp = new SodProblem2d(1.4, 0.5, 8, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_100t_8t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 7, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_100t_7t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 6, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_100t_6t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 5, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_100t_5t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 4, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_100t_4t.gdp");
	//}
	//delete sp;

	//sp = new SodProblem2d(1.4, 0.5, 1, false);
	//sp->initGrid(0.1, 1000, 10e-10, 10);
	//{
	//CProgressDlg dlg(sp, false);
	//dlg.solve(1.0, "C:\\Users\\Alexander\\Desktop\\sod2d\\sod2d_01x_1000_10p_100t_1t.gdp");
	//}
	//delete sp;

	//time = GetTickCount() - time;

	//char buf[512];
	//sprintf(buf, "Bunch of tests has completed in %dh %dm %s", time / 60 / 60000, (time / 60000) % 60, (time / 1000) % 60);

	//MessageBox(buf, "Message", MB_OK | MB_ICONINFORMATION);
}

void CRGDDlg::OnSimulationSaveavi()
{
	CFileDialog fileDlg(TRUE, _T(".gdp"), NULL, 0, _T("Gas Dynamics Problem (*.gdp)|*.gdp||"));
	if (fileDlg.DoModal() == IDOK)
	{
		Problem *pr = Problem::readProblem(fileDlg.GetPathName().GetBuffer(0));
		if (NULL == pr)
			MessageBox("Can't open file!", "Error", MB_OK | MB_ICONERROR);

		CAviDlg dlg;

		if (dlg.DoModal() == IDOK)
		{
			CFileDialog saveFileDlg(FALSE, _T(".avi"), NULL, 0, _T("AVI Files (*.avi)|*.avi||"));
			if (saveFileDlg.DoModal() == IDOK)
			{
				unsigned int w = dlg.m_width + 150;
				unsigned int h = dlg.m_height + 26;
				AviMemDc a(w, h, saveFileDlg.GetPathName().GetBuffer(), dlg.m_fps);

				CDC dc;
				dc.Attach(a);

				CRect dstRect(0, 0, w, h);

				unsigned int numFrames = pr->getNumSteps();
				for (unsigned int i = 0; i < numFrames; ++i)
				{
					while (!pr->plotSolution(dc, dstRect, m_jetColor, i, dlg.m_plot))
						;
					a.AddFrame();
				}
			}
			MessageBox("AVI File succesfully generated!", "Success!");
		}

		delete pr;
	}
}